home *** CD-ROM | disk | FTP | other *** search
- Subject: v07i014: Binary (file) patcher/viewer
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: pyramid!lukeII!itkin (Steven List)
- Mod.sources: Volume 7, Issue 14
- Archive-name: bpatch
-
-
-
- [ See me notes at the end of the README. --r$ ]
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
-
- # Exit status; set to 1 on "wc" errors or if would overwrite.
- STATUS=0
- # Contents: README Makefile bpatch.1 bpatch.c
-
- echo x - README
- if test -f README ; then
- echo README exists, putting output in $$README
- OUT=$$README
- STATUS=1
- else
- OUT=README
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F README//'
- XXHerewith find BPATCH - a marvelously utile utility. While not of
- XXmy original creation, I have been given permission to place in the
- XXpublic domain. I have made substantial modifications to the original
- XXsource given to me. Specifically I cleaned it up a bit and made it
- XXwork with SVR2 curses. Personally, I think it's pretty neat.
-
- XXOK - for those of you who may scream by now "WHAT THE HELL IS IT ALREADY?"
- XXI respond that it is a binary file editor and dump utility! That's
- XXright! You can dump your file in the nicely laid out side-by-side
- XXhex and ascii format or you can actually EDIT it at your terminal!
- XXYes, I have seen the BED editor that came across the network.
- XXUnfortunately, it converted the entire file before and after editing.
- XXBpatch, on the other hand, works with one 256 byte page at a time.
- XXIt is marvelously useful for looking at things like raw disk UNIFY
- XXdatabases and even raw disks! While the man page may not be absolutely
- XXup to date, the online help is. Try the question mark (?) command.
-
- XXAs always, I would love to hear about bugs/changes/enhancements/requests.
- XX Steven List @ Benetics Corporation, Mt. View, CA
- XX Just part of the stock at "Uncle Bene's Farm"
- XX {cdp,engfocus,idi,oliveb,opusys,plx,pyramid,tolerant}!bene!luke!itkin
-
- XXAddition by the moderator:
- XXI have added code, surrounded by #ifdef MOD_HAX, that gets bpatch
- XX(barely?) working on my 4.2 system. I would be very interested in
- XXpublishing a set of diffs that's less of a hack. Oh yeah: I also
- XXwrote the Makefile.
- XX /Rich $alz
- @//E*O*F README//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - Makefile
- if test -f Makefile ; then
- echo Makefile exists, putting output in $$Makefile
- OUT=$$Makefile
- STATUS=1
- else
- OUT=Makefile
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F Makefile//'
- XX# This may have to change on your system.
- XX# You may have to fiddle with various combinations of curses, termcap,
- XX# terminfo, etc. Good luck!
- XXLIBS = -lcurses -ltermcap
- XX#LIBS = -ltermlib
- XX#LIBS = -lterminfo
-
- XX# However you need getopt.
- XXGETOPT = -lgetopt
-
- XX# If you're running on a 4.[23] system, you probably want this.
- XXWORK = -DMOD_HAX
-
- XXCFLAGS = -O $(WORK)
-
- XXbpatch: bpatch.o
- XX $(CC) -o bpatch $(CFLAGS) bpatch.o $(GETOPT) $(LIBS)
-
- XXinstall:
- XX @echo Use cp to put things where you want them
- @//E*O*F Makefile//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - bpatch.1
- if test -f bpatch.1 ; then
- echo bpatch.1 exists, putting output in $$bpatch.1
- OUT=$$bpatch.1
- STATUS=1
- else
- OUT=bpatch.1
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F bpatch.1//'
- XX.TH "bpatch" "1" "Benetics Local"
- XX.if t .nr LL 7i
- XX.if t .nr IN .8i
- XX.if n .nr LL 70
- XX.if n .nr IN 8
- XX.fi
- XX.ad b
- XX.SH NAME
- XXbpatch - binary patch and dump file utility
- XX.SH SYNOPSIS
- XXbpatch [ -b blksize ] [ -d ] [ -D pagecnt ] [ -e ] [ -p ] [ -r reclen ] [ -s ] [ -x ] file...
- XX.SH DESCRIPTION
- XX\fIBpatch\fR allows the viewing and/or modification of files, independent of
- XXfile type (text, executable, data file, and so forth). \fIBpatch\fR
- XXallows the data to either be examined at the terminal, dumped to a print
- XXdevice or file, or edited in the general manner of \fIvi(1)\fR. The
- XXdata in the file is dumped or displayed in \fIpages\fR of 256 bytes.
- XX.SS Options
- XX.IP "-b blksize" 12
- XXThe \fI-b\fR option specifies the blocksize of the data file. This is used
- XXprimarily with tapes, and is allowed only with one of the dump (\fI-d\fR
- XXor \fI-D\fR) options. When this option is specified, the file is opened
- XXin readonly mode.
- XX.IP "-d" 12
- XXThe \fI-d\fR option indicates that a dump (no terminal manipulation) is
- XXto be performed. The entire file will be dumped to standard output. No
- XXediting of the data is allowed and the file is opened in readonly mode.
- XX.IP "-D pagecnt" 12
- XXThe \fI-D\fR option is similar to the \fI-d\fR option, with the
- XXfollowing exception: the pagecnt argument limits the dump to the
- XXspecified number of \fIpages\fR.
- XX.IP "-e" 12
- XXThe \fI-e\fR option indicates that the file contains EBCDIC data and
- XXshould be converted in the character portion of the dump.
- XX.IP "-p" 12
- XXUsed with one of the \fIdump\fR options, this option causes the program
- XXto pause between \fIpages\fR. The program will then wait for the user
- XXto press either the \fIreturn\fR key to continue, or the \fIDEL\fR (or
- XX\fIrubout\fR) key to stop the dump.
- XX.IP "-r reclen" 12
- XXThe \fI-r\fR option indicates the record length of the data within the
- XXdump. When specified, this option causes \fIbpatch\fR to place a colon
- XX(:) between the last byte of one record and the first byte of the next.
- XX.IP "-s" 12
- XXThis option turns on the byte swap option. It may be toggled dynamically
- XXduring execution (see \fI-x\fP under Commands below).
- XX.IP "-x" 12
- XXThis option specifies the suppression of pages that contain only NUL
- XXcharacters. The result is that only the page header (name and page
- XXnumber) will appear for such a page. This option may only be used with
- XXone of the dump options.
- XX.SS Arguments
- XX.IP file 12
- XXAny number of files may be specified.
- XX.SS Commands
- XXAll commands are valid only in the non-dump, interactive mode. Commands
- XXmay be entered in either upper or lower case. Commands of the form '^x'
- XXindicate that the control character \fIx\fR is to be entered.
- XX.P
- XXAll commands that request movement within a file or between files cannot
- XXbe executed if any changes have been made. To proceed in this case, the
- XXuser must either enter the \fIw\fR command, the \fIu\fR command, or the
- XX\fIr\fR command.
- XX.P
- XXRequesting a next or previous file when there is no such will cause the
- XXissuance of an error message.
- XX.P
- XXNote that certain commands allow/require either some text or numeric
- XXvalue. In those cases, the user should type in characters and end the
- XXstring with either a <cr> or <DEL>.
- XX.IP ? 6
- XXDisplay the help screen. The help screen will remain until the user
- XXeither redraws the screen (see \fI^r\fR) or changes pages or files.
- XX.IP ! 6
- XXExecute the following command in the shell.
- XX.IP backslash 6
- XXDisplay the previous page.
- XX.IP <cr> 6
- XXDisplay the next page.
- XX.IP DEL 6
- XXQuit the program if no changes have been made.
- XX.IP / 6
- XXThis command initiates an ASCII search. The text entered on the command
- XXline will be used as a search string, and the file will be searched
- XXstarting with the current page. When the string is found, the page
- XXcontaining the string will be displayed. If the string is not found, an
- XXapapropriate message will be displayed.
- XX.IP ^f 6
- XXOpen a named file whose name will be entered on the command line and
- XXfollowed either by <cr> or DEL.
- XX.IP ^n 6
- XXOpen the next file and display the first page.
- XX.IP ^p 6
- XXOpen the previous file and display the first page.
- XX.IP ^q 6
- XXQuit without writing current changes.
- XX.IP ^r 6
- XXRedraw the screen.
- XX.IP NNN 6
- XXEntering a numeric value requests that the specified page be displayed.
- XX.IP -x 6
- XXToggle the command line option represented by \fIx\fR:
- XX.RS 12
- XX.IP a 6
- XXToggle display to ascii (assume data is ascii).
- XX.IP e 6
- XXToggle display to dbcdic (assume data is ebcdic).
- XX.IP s 6
- XXToggle byte swap.
- XX.RE
- XX.IP a 6
- XXEdit the ASCII display. End edits by pressing the DEL key. All other
- XXcharacters will be treated as valid input. Cursor movement keys (arrows
- XXand home) allow movement within the edit window. Nonprinting
- XXcharacters are displayed as dot (.) in this window.
- XX.IP f 6
- XXDisplay the first page in the current file.
- XX.IP g 6
- XXDisplay the page containing the byte address typed in following the command.
- XX.IP h 6
- XXEdit the HEXADECIMAL display. End edits by pressing DEL key. Cursor
- XXmovement keys (arrows and home) allow movement within the edit window.
- XXTwo keystrokes are required to modify a byte, and both must be valid
- XXhexadecimal values (0-9 and a-f). To cancel a change after typing one
- XXcharacter, press DEL.
- XX.IP l 6
- XXDisplay the last page in the current file.
- XX.IP q 6
- XXQuit the file. A warning will be issued if any changes have been made
- XXbut not written out.
- XX.IP r 6
- XXReread the current page.
- XX.IP u 6
- XXUndo all changes to the current page.
- XX.IP w 6
- XXWrite out the current page.
- XX.SH "SEE ALSO"
- XXod(1)
- @//E*O*F bpatch.1//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo x - bpatch.c
- if test -f bpatch.c ; then
- echo bpatch.c exists, putting output in $$bpatch.c
- OUT=$$bpatch.c
- STATUS=1
- else
- OUT=bpatch.c
- fi
- sed 's/^XX//' > $OUT <<'@//E*O*F bpatch.c//'
- XX/*T bpatch - A binary file patch/dump utility */
- XX/*S Introduction */
- XX/*F bpatch ***********************************************************
- XX* bpatch
- XX* by Garry M Johnson - 09/17/84
- XX* (C) Copyright 1984, 1985
- XX*
- XX* Change History:
- XX* 03/05/86 - added further terminal independence
- XX* added use of ioctl (see main and mstdin)
- XX* added -D versus -d command line option
- XX* added use of standard getopt
- XX* cleaned up code, eliminated function "ikf"
- XX* added original versions of ezlib functions, such as
- XX* icc, setterm, cm, mstdin, erase, length, move
- XX* added ^R, ^Q, ^N, and ^P commands
- XX* added ^F, !, and ^X (-X) commands
- XX* changed name to "bpatch"
- XX* added direct address command (g)
- XX* added ASCII search capability
- XX* 07/07/86 - converted to use curses
- XX* modified direct addressing to use suffixes
- XX* updated HELP function
- XX*
- XX* Steven List @ Benetics Corporation, Mt. View, CA
- XX* {cdp,engfocus,idi,oliveb,plx,tolerant}!bene!luke!itkin
- XX*********************************************************************/
- XX/*E*/
- XX/*S includes, globals, and defines */
- XX/*Page Eject*/
- XX#include <curses.h>
- XX#include <fcntl.h>
- XX#include <signal.h>
- XX#include <ctype.h>
- XX#include <sys/types.h>
- XX#include <sys/stat.h>
-
- XXstatic int pbrk = 0;
- XXstruct stat sb;
-
- XXvoid icc ();
- XXvoid copyrec ();
- XXvoid schwapp ();
-
- XX /* ------------------------------------------------------------ */
- XX /* Some defines added by the moderator to get it work on 4.2 */
- XX /* ------------------------------------------------------------ */
- XX#ifdef MOD_HAX
- XX /* Fifos? We ain't got no steenkin' fifos. */
- XX#define S_IFIFO 123450
- XX /* "Spelling differences." */
- XX#define beep() fprintf (stderr, "\007")
- XX#define cbreak() crmode()
- XX /* Our curses doesn't translate keypad keys to single characters. */
- XX#define keypad(a, b) /* null */
- XX#define KEY_UP '^'
- XX#define KEY_DOWN 'v'
- XX#define KEY_LEFT '<'
- XX#define KEY_RIGHT '>'
- XX#define KEY_HOME '@'
- XX#endif /* MOD_HAX */
-
-
- XX /* ------------------------------------------------------------ */
- XX /* Some convenient defines */
- XX /* ------------------------------------------------------------ */
-
- XX#define DEL '\177'
- XX#define HEX 1
- XX#define ALPHA 0
-
- XX /* ------------------------------------------------------------ */
- XX /* general purpose identification and control variables */
- XX /* ------------------------------------------------------------ */
-
- XXchar filename[64]; /* current file being examined */
- XXchar record[16][16]; /* record (page) buffer */
- XXchar unch_rec[16][16]; /* record before any changes */
- XXint zp; /* current input character */
-
- XXint block = 0; /* block size if -b in command */
- XXint block_spec; /* true if file is block special */
- XXint bytes = 0; /* number of bytes from last read */
- XXint char_spec; /* true if file is char special */
- XXint debug = 0; /* true if debug is turned on */
- XXint dir_spec; /* true if file is directory */
- XXint dump = 0; /* nonzero if dump instead of change*/
- XXint ebcdic = 0; /* true if -e option */
- XXint fifo_spec; /* true if file is fifo */
- XXint honly = 0; /* true if dump is to be hex only */
- XXint mod = 0; /* true if record has been modified */
- XXint pause = 0; /* true if -p option */
- XXint rawfile = 0; /* true if file is c/b/p */
- XXint reclen = 0; /* record length, if -r */
- XXint recno = 0; /* current record (page) number */
- XXint stay = 0; /* true if no position change */
- XXint swab = 0; /* true if byte swapping is on */
- XXint windowed = 0; /* true if windowing - not dump */
-
- XXlong position = 0; /* byte address in file */
-
- XXWINDOW *hexwin = NULL;
- XXWINDOW *alphawin = NULL;
- XXWINDOW *errwin = NULL;
-
- XX/*S main - control all the work from here */
- XX/*H main *************************************************************
- XX*
- XX* main
- XX*
- XX* set up the globals, initilize the state, and process the file
- XX*
- XX*********************************************************************/
- XX/*E*/
- XXmain (argc, argv)
- XXint argc;
- XXchar *argv[];
- XX{
- XX extern WINDOW *subwin ();
- XX extern WINDOW *newwin ();
-
- XX#ifdef MOD_HAX
- XX#else /* use original code... */
- XX struct termio asis;
- XX#endif /* MOD_HAX */
-
- XX register char *cp; /* general purpose char ptr */
- XX extern char *gets (); /* get string from stdin */
- XX char m = '\017'; /* mask for hex edit */
- XX char response[512]; /* general purpose buffer */
- XX int z; /* character read in */
- XX
- XX int breakp (); /* signal trapping function */
- XX int c; /* current screen column */
- XX int change = 0; /* true if cmd line option toggled */
- XX int fid; /* file descriptor */
- XX int firstfile; /* arg # of first file in cmd line */
- XX int h; /* temp for hex edit */
- XX int i; /* general purpose loop index */
- XX int j; /* general purpose loop index */
- XX int r; /* current screen row */
- XX int hexc; /* current cursor column in hexwin */
-
- XX long byteaddr; /* planned byte address for 'G' */
- XX long size; /* file size in bytes */
- XX long status; /* EOF if at end of file or error */
-
- XX extern int optind; /* getopt index into argv */
- XX extern char *optarg; /* getopt pointer to opt arg */
-
- XX extern long getnum ();
- XX extern char *instr (); /* get a string from the cmd line */
- XX extern int reset (); /* exit function - reset terminal */
-
- XX /* ------------------------------------------------------------ */
- XX /* set up signal handling */
- XX /* ------------------------------------------------------------ */
-
- XX if (!dump) signal (SIGINT, breakp);
-
- XX signal (SIGTERM, reset);
-
- XX /* ------------------------------------------------------------ */
- XX /* process command line arguments */
- XX /* ------------------------------------------------------------ */
-
- XX while ((i = getopt (argc, argv, "r:dD:b:pxXse")) != EOF)
- XX {
- XX switch (i)
- XX {
- XX case 'b': /* blocking */
- XX block = atoi (optarg);
- XX if (block < 1 || block > 10240)
- XX {
- XX fprintf (stderr,
- XX "invalid block size: %d\n", block);
- XX exit (1);
- XX }
- XX break;
- XX case 'd': /* straight dump - no limit */
- XX dump = -1;
- XX break;
- XX case 'D': /* dump - page count spec */
- XX dump = atoi (optarg);
- XX break;
- XX case 'e': /* file is ebcdic */
- XX ebcdic = 1;
- XX break;
- XX case 'p': /* pause between pages - dump */
- XX pause = 1;
- XX break;
- XX case 'r': /* record length for dump */
- XX reclen = atoi (optarg);
- XX break;
- XX case 's': /* byte swapping required */
- XX swab = 1;
- XX break;
- XX case 'x': /* hex dump only */
- XX honly = 1;
- XX break;
- XX case 'X':
- XX debug = 1;
- XX break;
- XX default: /* uhoh */
- XX fprintf (stderr,
- XX"usage: bpatch [ -b blocksz ] [ -d<ump> ] [ -D pagecnt ] [ -e<bcdic> ]\n");
- XX fprintf (stderr,
- XX" [ -p<ause> ] [ -r reclen ] [ -s<wap bytes> ] [ -x<only> ]\n");
- XX exit (1);
- XX }
- XX }
-
- XX /* ------------------------------------------------------------ */
- XX /* check for valid combinations of options */
- XX /* ------------------------------------------------------------ */
-
- XX if ((honly || block || reclen || pause ) && !dump)
- XX {
- XX fprintf (stderr, "-x|-b|-r|-p requires -d or -D\n");
- XX exit (2);
- XX }
-
- XX /* ------------------------------------------------------------ */
- XX /* At least one file name must be specified on the cmd line */
- XX /* ------------------------------------------------------------ */
-
- XX if (optind == argc)
- XX {
- XX fprintf (stderr, "no file name(s) specified\n");
- XX exit (2);
- XX }
-
- XX /* ------------------------------------------------------------ */
- XX /* set up the screen, if this is an interactive session */
- XX /* ------------------------------------------------------------ */
-
- XX if (!dump)
- XX {
- XX windowed = 1;
- XX initscr ();
- XX nonl ();
- XX noecho ();
- XX cbreak ();
- XX keypad (stdscr, TRUE);
- XX hexwin = subwin (stdscr, 16, 48, 4, 4);
- XX keypad (hexwin, TRUE);
- XX alphawin = subwin (stdscr, 16, 16, 4, 57);
- XX keypad (alphawin, TRUE);
- XX errwin = subwin (stdscr, 1, 80, 23, 0);
-
- XX#ifdef MOD_HAX
- XX /* This is not exactly what the original code does,
- XX but it's good enough. -r$ */
- XX raw();
- XX#else /* use original code... */
- XX ioctl (0, TCGETA, &asis);
- XX asis.c_cc[VINTR] = '\0';
- XX asis.c_iflag &= ~IXON;
- XX asis.c_iflag &= ~IXOFF;
- XX asis.c_iflag &= ~IXANY;
- XX ioctl (0, TCSETA, &asis);
- XX#endif /* MOD_HAX */
- XX }
-
- XX /* ------------------------------------------------------------ */
- XX /* save the first file's index for backing up later */
- XX /* ------------------------------------------------------------ */
-
- XX firstfile = optind;
-
- XX /* ------------------------------------------------------------ */
- XX /* open the first file */
- XX /* ------------------------------------------------------------ */
-
- XX for (fid = -1; fid < 0 && optind < argc;)
- XX {
- XX fid = ckfile (argv[optind], &size);
- XX if (fid < 0) optind++;
- XX }
- XX if (fid < 0)
- XX {
- XX fprintf (stderr, "could not handle the file list\n");
- XX exit (2);
- XX }
-
- XX strncpy (filename, argv[optind], sizeof filename);
-
- XX if (block != 0)
- XX {
- XX size = -1;
- XX }
-
- XX recno = 0;
- XX stay = 0;
- XX mod = 0;
- XX status = 0;
-
- XX /* ------------------------------------------------------------ */
- XX /* Until the user exits... */
- XX /* ------------------------------------------------------------ */
-
- XX if (!dump) clear ();
-
- XX while (status != EOF)
- XX {
- XX /* ------------------------------------------------------------ */
- XX /* change of location - read and display */
- XX /* ------------------------------------------------------------ */
- XX if (stay == 0)
- XX {
- XX position = lseek (fid, (long)(recno * 256), 0);
-
- XX if ((bytes = bread (fid, record, 256, block)) < 0)
- XX {
- XX errmsg ("error on reading file %s", filename);
- XX status = EOF;
- XX continue;
- XX }
- XX if (bytes > 0)
- XX {
- XX if (swab) schwapp (record, 256);
-
- XX copyrec (record, unch_rec, sizeof record);
-
- XX show (bytes, record, filename, size, recno,
- XX position, m,reclen, dump, ebcdic, swab,
- XX block, honly);
- XX }
- XX mod = 0;
- XX }
- XX /* ------------------------------------------------------------ */
- XX /* not interactive - keep dumping or open next file */
- XX /* ------------------------------------------------------------ */
- XX if (dump)
- XX {
- XX if ((dump < 0 && bytes == 0) || (--dump == 0))
- XX {
- XX if (optind == argc) status = EOF;
- XX else
- XX {
- XX close (fid);
- XX fid = -1;
- XX for (optind++; fid < 0 && optind < argc;)
- XX {
- XX fid = ckfile (argv[optind], &size);
- XX if (fid < 0) optind++;
- XX }
-
- XX strncpy (filename, argv[optind], sizeof filename);
-
- XX if (block != 0)
- XX {
- XX size = -1;
- XX }
- XX recno = 0;
- XX stay = 0;
- XX status = lseek (fid, (long)0, 0);
- XX }
- XX }
- XX ++recno;
- XX /* ------------------------------------------------------------ */
- XX /* if pause, beep and wait */
- XX /* ------------------------------------------------------------ */
- XX if (status != EOF && pause)
- XX {
- XX pbrk = 0;
- XX fprintf (stderr, "\007");
- XX gets (response);
-
- XX if (pbrk) status = EOF;
- XX }
-
- XX continue;
- XX }
- XX /* ------------------------------------------------------------ */
- XX /* if we got here, this is an interactive session */
- XX /* ------------------------------------------------------------ */
- XX stay = 0;
- XX move (22, 0);
- XX /* ------------------------------------------------------------ */
- XX /* get the user's command */
- XX /* ------------------------------------------------------------ */
- XX response[0] = EOF;
- XX mvaddstr (22, 0, "> ");
- XX clrtoeol ();
- XX refresh ();
- XX zp = getch ();
-
- XX if (debug && !dump)
- XX {
- XX if (isascii (zp) && isprint (zp))
- XX errmsg ("command entered is %c", zp);
- XX else errmsg ("command entered is ^%c (%#x)", zp + '@', zp);
- XX getch ();
- XX }
-
- XX if (isascii (zp) && isalpha (zp) && islower (zp))
- XX zp = toupper (zp);
- XX /* ------------------------------------------------------------ */
- XX /* here we go - what does the user want? */
- XX /* ------------------------------------------------------------ */
- XX refresh ();
-
- XX switch (zp)
- XX {
- XX case '!': /* shell escape */
- XX echo ();
- XX move (23,0);
- XX clrtoeol ();
- XX addstr ("shell command: ");
- XX refresh ();
- XX getstr (response);
- XX erase ();
- XX refresh ();
- XX nl ();
- XX system (response);
- XX noecho ();
- XX nonl ();
- XX move (23,0);
- XX standout ();
- XX addstr (" <Press any key> ");
- XX standend ();
- XX clrtoeol ();
- XX refresh ();
- XX getch ();
- XX clear ();
- XX break;
-
- XX case '?': /* HELP */
- XX dbg_msg ("Help");
- XX dohelp ();
- XX touchwin (stdscr);
- XX refresh ();
- XX stay = 1;
- XX break;
-
- XX case '/': /* search for a string */
- XX stay = 1;
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX }
- XX else search (fid, zp);
- XX break;
-
- XX case '-': /* toggle options */
- XX zp = getch ();
- XX stay = 1;
- XX change = 0;
- XX switch (zp)
- XX {
- XX case 'a': /* ascii */
- XX if (ebcdic)
- XX {
- XX dbg_msg ("toggle to ascii");
- XX change = 1;
- XX }
- XX ebcdic = 0;
- XX break;
-
- XX case 'e': /* ebcdic */
- XX if (ebcdic == 0)
- XX {
- XX dbg_msg ("toggle to ebcdic");
- XX change = 1;
- XX }
- XX ebcdic = 1;
- XX break;
-
- XX case 's': /* swab */
- XX dbg_msg ("toggle byte swap");
- XX change = 1;
- XX schwapp (record, 256);
- XX swab = !swab;
- XX break;
- XX }
- XX if (change)
- XX {
- XX show (bytes, record, filename, size,
- XX recno, position, m,reclen, dump,
- XX ebcdic, swab, block, honly);
- XX }
-
- XX break;
-
- XX case '\022': /* redraw screen (^R) */
- XX clear ();
- XX show (bytes, record, filename, size, recno,
- XX position, m, reclen, dump, ebcdic,
- XX swab, block, honly);
- XX stay = 1;
- XX break;
- XX
- XX case '\030': /* toggle debug (^X) */
- XX debug = !debug;
- XX break;
-
- XX case '\006': /* new file (^F) */
- XX close (fid);
- XX fid = ckfile (cp = instr (), &size);
- XX if (fid < 0)
- XX {
- XX fid = ckfile (filename, &size);
- XX }
- XX else
- XX {
- XX strncpy (filename, cp, sizeof filename);
- XX stay = 0;
- XX recno = 0;
- XX }
- XX break;
-
- XX case '\016': /* next file (^N) */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else if (optind == (argc - 1))
- XX {
- XX errmsg ("No more files");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX close (fid);
- XX for (fid = -1, optind++; fid < 0 && optind < argc;)
- XX {
- XX fid = ckfile (argv[optind], &size);
- XX if (fid < 0) optind++;
- XX }
- XX if (fid < 0)
- XX {
- XX errmsg ("could not handle the file list");
- XX reset (0);
- XX }
- XX strncpy (filename, argv[optind], sizeof filename);
- XX stay = 0;
- XX recno = 0;
- XX }
- XX break;
-
- XX case '\020': /* prev file (^P) */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else if (optind == firstfile)
- XX {
- XX errmsg ("No previous file");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX close (fid);
- XX for (fid = -1, optind--; fid < 0 && optind >= firstfile;)
- XX {
- XX fid = ckfile (argv[optind], &size);
- XX if (fid < 0) optind--;
- XX }
- XX if (fid < 0)
- XX {
- XX errmsg ("could not handle the file list");
- XX reset (0);
- XX }
- XX strncpy (filename, argv[optind], sizeof filename);
- XX stay = 0;
- XX recno = 0;
- XX }
- XX break;
-
- XX case '\021': /* quit absolutely (^Q) */
- XX status = EOF;
- XX break;
-
- XX case DEL: /* quit with check */
- XX case 'Q': /* quit */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change!");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX status = EOF;
- XX }
- XX break;
-
- XX case '\\': /* back up 1 record */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX if (recno > 0)
- XX {
- XX --recno;
- XX stay = 0;
-
- XX status = lseek (fid, (long)recno*256, 0);
- XX if (status < 0)
- XX {
- XX move (22, 0);
- XX clrtoeol ();
- XX perror (filename);
- XX errmsg ("error positioning in file");
- XX beep ();
- XX ++recno;
- XX stay = 1;
- XX }
- XX }
- XX else
- XX {
- XX errmsg ("No previous records");
- XX beep ();
- XX stay = 1;
- XX }
- XX }
- XX break;
-
- XX case 'F': /* go to first record */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX status = lseek (fid, (long)0, 0);
- XX recno = 0;
- XX }
- XX break;
-
- XX case 'L': /* go to last record */
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX position = lseek (fid, (long)0, 2);
- XX recno = position / 256;
- XX j = position % 256;
- XX if (j == 0) --recno;
- XX status = lseek (fid, (long)(recno*256), 0);
- XX }
- XX break;
-
- XX case 'U': /* undo changes */
- XX stay = 1;
- XX mod = 0;
- XX copyrec (unch_rec, record, sizeof record);
- XX show (bytes, record, filename, size, recno,
- XX position, m,reclen, dump, ebcdic, swab,
- XX block, honly);
- XX break;
-
- XX case 'R': /* re-read record */
- XX status = lseek (fid, (long)recno*256, 0);
- XX break;
-
- XX case '0': /* go to some address */
- XX case '1':
- XX case '2':
- XX case '3':
- XX case '4':
- XX case '5':
- XX case '6':
- XX case '7':
- XX case '8':
- XX case '9':
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX byteaddr = getnum (zp, FALSE);
- XX stay = 1;
- XX errmsg ("Position to byte %ld", byteaddr);
- XX if (!rawfile && byteaddr > size)
- XX {
- XX errmsg ("Address outside file");
- XX beep ();
- XX }
- XX else if (byteaddr / 256 != recno)
- XX {
- XX recno = byteaddr / 256;
- XX status = lseek (fid, (long)recno * 256, 0);
- XX stay = 0;
- XX }
- XX }
- XX break;
-
- XX case 'A': /* alpha modify */
- XX stay = 1;
- XX r = c = 0;
- XX dbg_msg ("edit ascii");
- XX if (bytes == 0) break;
- XX touchwin (stdscr);
- XX refresh ();
- XX wmove (alphawin, r, c);
- XX wrefresh (alphawin);
-
- XX while ((z = wgetch (alphawin)) != DEL)
- XX {
- XX if (!arrow (z, &r, &c))
- XX {
- XX if (isascii (z))
- XX {
- XX if (isprint (z)) waddch (alphawin, z);
- XX else waddch (alphawin, '.');
-
- XX if (ebcdic) icc (&z, 1,"AE");
-
- XX record[r][c] = z;
- XX mod = 1;
-
- XX hexc = c * 3;
- XX wmove (hexwin, r, hexc);
- XX if (record[r][c] < '\0')
- XX {
- XX wprintw (hexwin, "%x%x",
- XX (record[r][c] >> 4) & m,
- XX record[r][c] & m);
- XX }
- XX else
- XX {
- XX wprintw (hexwin, "%02x", record[r][c]);
- XX }
- XX wrefresh (hexwin);
-
- XX }
- XX else
- XX {
- XX beep ();
- XX }
-
- XX if (c == 15)
- XX {
- XX if (r == 15) beep ();
- XX else
- XX {
- XX c = 0;
- XX ++r;
- XX }
- XX }
- XX else
- XX {
- XX c++;
- XX }
- XX }
- XX if (r * 16 + c >= bytes)
- XX {
- XX beep ();
- XX r = (bytes - 1) / 16;
- XX c = (bytes - 1) % 16;
- XX }
-
- XX wmove (alphawin, r, c);
- XX wrefresh (alphawin);
- XX }
-
- XX break;
-
- XX case 'H': /* hex modify */
- XX dbg_msg ("edit hex");
- XX stay = 1;
- XX r = c = hexc = 0;
- XX if (bytes == 0) break;
- XX touchwin (stdscr);
- XX refresh ();
- XX wmove (hexwin, r, hexc);
- XX wrefresh (hexwin);
-
- XX while ((z = wgetch (hexwin)) != DEL)
- XX {
- XX if (!arrow (z, &r, &c))
- XX {
- XX hexc = c * 3;
- XX z = toupper (z);
- XX if (!isxdigit (z))
- XX {
- XX beep ();
- XX }
- XX else
- XX {
- XX waddch (hexwin, tolower (z));
- XX wrefresh (hexwin);
-
- XX if (z > '9') z -= 7;
-
- XX h = (z & m) << 4;
-
- XX while (2)
- XX {
- XX z = EOF;
- XX z = getch ();
- XX if (z == EOF)
- XX {
- XX pbrk = 0;
- XX h = -1;
- XX break;
- XX }
- XX z = toupper (z);
- XX if (!isxdigit (z))
- XX {
- XX beep ();
- XX }
- XX else
- XX {
- XX waddch (hexwin, tolower (z));
- XX wrefresh (hexwin);
- XX if (z > '9') z -= 7;
-
- XX h |= z & m;
- XX break;
- XX }
- XX }
-
- XX if (h < 0)
- XX {
- XX wmove (hexwin, r, hexc);
- XX if (record[r][c] < '\0')
- XX {
- XX wprintw (hexwin, "%x%x",
- XX (record[r][c] >> 4) & m,
- XX record[r][c] & m);
- XX }
- XX else
- XX {
- XX wprintw (hexwin, "%02x", record[r][c]);
- XX }
- XX wrefresh (hexwin);
- XX break;
- XX }
-
- XX record[r][c] = z = h;
- XX mod = 1;
-
- XX if (ebcdic) icc (&z, 1,"EA");
-
- XX wmove (alphawin, r, c);
- XX if (isascii (z) && isprint (z))
- XX waddch (alphawin, z);
- XX else waddch (alphawin, '.');
- XX wrefresh (alphawin);
-
- XX if (c == 15)
- XX {
- XX if (r == 15) beep ();
- XX else
- XX {
- XX c = 0;
- XX ++r;
- XX }
- XX }
- XX else
- XX {
- XX c++;
- XX }
- XX }
- XX }
-
- XX if (r * 16 + c >= bytes)
- XX {
- XX beep ();
- XX r = (bytes - 1) / 16;
- XX c = (bytes - 1) % 16;
- XX }
-
- XX hexc = c * 3;
- XX wmove (hexwin, r, hexc);
- XX wrefresh (hexwin);
- XX }
- XX break;
-
- XX case 'W': /* write record */
- XX stay = 1;
- XX status = lseek (fid, position, 0);
- XX if (status != position)
- XX {
- XX move (22, 0);
- XX clrtoeol ();
- XX perror (filename);
- XX errmsg ("error positioning in file");
- XX beep ();
- XX }
- XX if (swab) schwapp (record, 256);
- XX if (write (fid, record, bytes) != bytes)
- XX {
- XX errmsg ("error writing to file");
- XX sleep (1);
- XX reset (0);
- XX exit (0);
- XX }
- XX if (swab) schwapp (record, 256);
- XX mod = 0;
- XX errmsg ("Record written");
- XX break;
-
- XX case '\n': /* newline - next page */
- XX case '\r':
- XX if (mod)
- XX {
- XX errmsg ("No write since last change");
- XX stay = 1;
- XX }
- XX else
- XX {
- XX ++recno;
- XX if (!rawfile && (recno * 256) >= size)
- XX {
- XX recno--;
- XX beep ();
- XX errmsg ("No more records in file");
- XX stay = 1;
- XX }
- XX else stay = 0;
- XX }
- XX break;
-
- XX default:
- XX if (isascii (zp) && isprint (zp))
- XX errmsg ("Unknown command: %d", zp);
- XX else
- XX errmsg ("Unknown command: %d", zp + '@');
- XX beep ();
- XX stay = 1;
- XX break;
- XX } /* end switch zp */
- XX refresh ();
- XX }
-
- XX if (windowed)
- XX {
- XX reset (0);
- XX }
- XX status = close (fid);
-
- XX exit (status);
- XX}
- XX/*S show - display a record on the terminal */
- XX/*H show */
- XX/*E*/
- XXshow (bytes, record, filename, size, recno, position,
- XX m,reclen, dump, ebcdic, swab, block, honly)
- XXint bytes;
- XXint size;
- XXint recno;
- XXint position;
- XXint m;
- XXint reclen;
- XXint dump;
- XXint ebcdic;
- XXint swab;
- XXint honly;
- XXchar record[16][16];
- XXchar *filename;
- XX{
- XX int i;
- XX int j;
- XX char s;
- XX char temp[16];
- XX char *look = NULL;
-
- XX int row = 0;
- XX int col = 0;
-
- XX if (dump) printf ("\n\n");
-
- XX if (debug)
- XX {
- XX getyx (stdscr, row, col);
- XX move (23,0);
- XX printw ("show: %d|%d|%s|%d|%d|%d|%#x|%d|%d|%d|%d|%d|%d",
- XX bytes, record, filename, size, recno, position,
- XX m, reclen, dump, ebcdic, swab, block, honly);
- XX move (row, col);
- XX row = col = 0;
- XX }
-
- XX if (!dump) move (0, 0);
- XX outstr ("FILE: %s ", filename);
- XX if (block_spec) outstr ("(block special)");
- XX else if (char_spec) outstr ("(character special)");
- XX else if (fifo_spec) outstr ("(fifo (named pipe))");
- XX else if (dir_spec) outstr ("(directory - %ld)", size);
- XX else outstr ("(%ld)", size);
-
- XX if (ebcdic) outstr (" - EBCDIC");
- XX else outstr (" - ASCII");
- XX if (swab) outstr (" - SWAP");
- XX if (block) outstr (" - BLOCK (%d)", block);
- XX if (reclen) outstr (" - RECORD (%d)", reclen);
-
- XX if (!dump)
- XX {
- XX clrtoeol ();
- XX move (1,0);
- XX printw ("PAGE: %d (%d)", recno, position);
- XX clrtoeol ();
- XX row = 2;
- XX }
- XX else
- XX {
- XX printf ("\nPAGE: %d (%d)\n", recno, position);
- XX }
-
- XX if (honly)
- XX {
- XX look = (char *) record;
- XX for (j=0;j<256;++j)
- XX {
- XX if (*look++ != '\0')
- XX {
- XX look = NULL;
- XX break;
- XX }
- XX }
- XX }
-
- XX if (!dump) move (row, col);
-
- XX outstr (" x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf");
- XX outstr (" 0123456789abcdef");
-
- XX if (!dump)
- XX {
- XX row += 2;
- XX move (row, col);
- XX }
- XX else
- XX {
- XX printf ("\n\n");
- XX }
- XX for (i=0; i<=bytes/16; ++i)
- XX {
- XX if (honly && look != NULL)
- XX {
- XX i = 16;
- XX continue;
- XX }
- XX if (i*16+1 > bytes) continue;
-
- XX outstr ("%02x: ", i);
-
- XX for (j=0; j<16; ++j)
- XX {
- XX if (i*16+j < bytes)
- XX {
- XX if (record[i][j] < '\0')
- XX outstr ("%x%x ",
- XX (record[i][j] >> 4) & m, record[i][j] & m);
- XX else
- XX outstr ("%02x ", record[i][j]);
-
- XX s = ' ';
- XX if (reclen > 0 && (position+i*16+j+1)%reclen == 0)
- XX s = ':';
- XX if (block > 0 && (position+i*16+j+1)%block == 0)
- XX {
- XX if (s == ' ')
- XX s = '/';
- XX else
- XX s = '%';
- XX }
- XX if (s != ' ')
- XX outstr ("\b%c", s);
- XX }
- XX else
- XX {
- XX outstr (" ");
- XX }
- XX }
-
- XX outstr (" ");
-
- XX copyrec (record[i], temp, 16);
-
- XX if (ebcdic) icc (temp, 16, "EA");
-
- XX for (j = 0; j < 16 && i*16+j < bytes; ++j)
- XX {
- XX if (temp[j] < ' ') outch ('.');
- XX else outstr ("%c", temp[j]);
- XX }
-
- XX if (!dump)
- XX {
- XX move (++row, col);
- XX }
- XX else
- XX {
- XX printf ("\n");
- XX }
- XX }
-
- XX if (!dump)
- XX {
- XX clrtobot ();
- XX refresh ();
- XX }
-
- XX return;
- XX}
- XX/*S breakp - set pbrk on interrupt */
- XX/*H breakp */
- XX/*E*/
- XXint breakp (i)
- XXint i;
- XX{
- XX int s;
- XX extern int pbrk;
- XX s = (int) signal (SIGINT, breakp);
- XX pbrk = i;
- XX}
- XX/*S bread - buffered read */
- XX/*H bread */
- XX/*E*/
- XXint bread (fid, record, want, block)
- XXint fid, want, block;
- XXchar *record;
- XX{
- XX int i, j, k;
- XX int what, bytes, orig;
- XX static char buffer[10240];
- XX static int left, arrow;
- XX static int flag = 1;
-
- XX if (flag)
- XX {
- XX left = 0;
- XX arrow = 0;
- XX flag = 0;
- XX }
-
- XX if (block == 0)
- XX return (read (fid, record, want));
-
- XX if (block & 1) ++block;
-
- XX orig = what = want;
- XX while (1)
- XX {
- XX if (left < want)
- XX {
- XX if (left)
- XX {
- XX copyrec (&buffer[arrow], record, left);
- XX record += left;
- XX want -= left;
- XX }
-
- XX arrow = 0;
- XX left = 0;
-
- XX if ((bytes = read (fid, buffer, block)) < 0)
- XX {
- XX what = bytes;
- XX break;
- XX }
-
- XX if (bytes == 0)
- XX {
- XX what = orig - want;
- XX break;
- XX }
-
- XX left = bytes;
- XX }
- XX else
- XX {
- XX copyrec (&buffer[arrow], record, want);
- XX arrow += want;
- XX left -= want;
- XX break;
- XX }
- XX }
-
- XX return (what);
- XX}
- XX/*S schwapp - swap bytes in place */
- XX/*H schwapp */
- XX/*E*/
- XXvoid
- XXschwapp (ptr, nch)
- XXregister char *ptr;
- XXregister int nch;
- XX{
- XX register int i;
- XX register char c;
- XX register char *ptra = ptr + 1;
-
- XX if (nch & 1) --nch;
-
- XX for (i = 0; i < nch; i += 2, ptr += 2, ptra += 2)
- XX {
- XX c = *ptr;
- XX *ptr = *ptra;
- XX *ptra = c;
- XX }
- XX return;
- XX}
- XX/*S copyrec - transfer bytes from f to t for nbytes bytes */
- XX/*H copyrec */
- XX/*E*/
- XXvoid
- XXcopyrec (f, t, nbytes)
- XXregister char *f;
- XXregister char *t;
- XXregister int nbytes;
- XX{
- XX register int i;
-
- XX for (i = 0; i < nbytes; i++, f++, t++) *t = *f;
-
- XX return;
- XX}
- XX/*S ebcdic codes corresponding to ascii - translation table */
- XX/*Page Eject*/
- XXchar ebcdic_codes[] = {
- XX0, 0x1, 0x2, 0x3, 0x37, 0x2d, 0x2e, 0x2f, 0x16,
- XX0x5, 0x25, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
- XX0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f,
- XX0x27, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x5a, 0x7f, 0x7b,
- XX0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b,
- XX0x60, 0x4b, 0x61, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5,
- XX0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e,
- XX0x6f, 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
- XX0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
- XX0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
- XX0xe9, 0xad, 0xe0, 0xbd, 0x9a, 0x6d, 0x79, 0x81, 0x82,
- XX0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92,
- XX0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0xa2, 0xa3,
- XX0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0,
- XX0x5f, 0x7 };
- XX/*S icc - internal code conversion */
- XX/*H icc */
- XX/*E*/
- XXvoid
- XXicc (buf, nch, type)
- XXregister char *buf;
- XXregister int nch;
- XXchar *type;
- XX{
- XX register int i;
- XX register int j;
-
- XX if (!strcmp (type, "AE"))
- XX {
- XX for (i = 0; i < nch; i++, buf++)
- XX {
- XX *buf = ebcdic_codes[*buf];
- XX }
- XX }
- XX else if (!strcmp (type, "EA"))
- XX {
- XX for (i = 0; i < nch; i++, buf++)
- XX {
- XX for (j = 0; j < 128; j++)
- XX {
- XX if (*buf == ebcdic_codes[j])
- XX {
- XX *buf = j;
- XX break;
- XX }
- XX }
- XX }
- XX }
-
- XX return;
- XX}
- XX/*S ckfile - check on existence, accessibility, and type of file */
- XX/*H ckfile */
- XX/*E*/
- XXckfile (filename, sizep)
- XXchar *filename;
- XXlong *sizep;
- XX{
- XX register int fid = 0;
-
- XX if (access (filename, 0) < 0)
- XX {
- XX errmsg ("file not found (%s)", filename);
- XX fid = -1;
- XX }
-
- XX if (block || pause || dump)
- XX {
- XX fid = open (filename, O_RDONLY, 0);
- XX }
- XX else
- XX {
- XX fid = open (filename, O_RDWR, 0);
- XX }
-
- XX if (fid < 0)
- XX {
- XX errmsg ("error opening file %s", filename);
- XX perror (filename);
- XX fid = -1;
- XX }
- XX else
- XX {
- XX errmsg ("File %s opened successfully ", filename);
- XX if (fstat (fid, &sb) == -1)
- XX {
- XX fprintf (stderr, "Can't stat\n");
- XX perror (filename);
- XX fid = -1;
- XX }
- XX else
- XX {
- XX block_spec = (sb.st_mode & S_IFMT) == S_IFBLK;
- XX char_spec = (sb.st_mode & S_IFMT) == S_IFCHR;
- XX fifo_spec = (sb.st_mode & S_IFMT) == S_IFIFO;
- XX dir_spec = (sb.st_mode & S_IFMT) == S_IFDIR;
- XX rawfile = block_spec || char_spec || fifo_spec;
-
- XX if (rawfile) *sizep = -1;
- XX else
- XX {
- XX if (sb.st_size == 0)
- XX {
- XX fprintf (stderr,
- XX "file %s is empty (zero bytes)\n",
- XX filename);
- XX fid = -1;
- XX }
- XX *sizep = sb.st_size;
- XX }
- XX }
- XX }
-
- XX return fid;
- XX}
- XX/*S dohelp - display help text */
- XX/*H dohelp */
- XX/*E*/
- XXdohelp ()
- XX{
- XX static char *helptxt[] = {
- XX "! - execute command in the shell", "a - edit ascii portion",
- XX "-x - toggle command line option", "f - display first page of file",
- XX "<cr> - display next page", NULL,
- XX "? - display this help text", "h - edit hexadecimal portion",
- XX "DEL - quit the program", "l - display last page of file",
- XX "\\ - display previous page", "nnn - direct addressing",
- XX "/ - search for ASCII string", "q - quit the program",
- XX "^f - select named file", "r - reread the current page",
- XX "^n - select next file", "u - undo all changes to page",
- XX "^p - select previous file", "w - write out changed page",
- XX "^q - quit without writing changes", NULL,
- XX "^r - redraw the screen", NULL,
- XX "^x - turn on debug", NULL,
- XX "----------------------------------------------------------------", NULL,
- XX "direct addressing: nnnS, where nnn = some number, and", NULL,
- XX " S = type suffix", "b = block (512)",
- XX NULL, "k = kilobyte (1024)",
- XX NULL, "l = long word (4)",
- XX NULL, "p = page (256)",
- XX NULL, "w = word (2)",
- XX NULL, "<cr> = byte",
- XX };
-
- XX static int nmsg = sizeof helptxt / sizeof (char *);
- XX register int row = 0;
- XX register int i;
-
- XX register WINDOW *helpwin;
- XX extern WINDOW *newwin ();
-
- XX helpwin = newwin (LINES, COLS, 0, 0);
- XX werase (helpwin);
- XX wrefresh (helpwin);
-
- XX wmove (helpwin, 0, 1);
- XX waddstr (helpwin,
- XX"---------------------------------- HELP ----------------------------------");
-
- XX for (row = 1, i = 0; i < nmsg; i+=2)
- XX {
- XX if (helptxt[i])
- XX {
- XX wmove (helpwin, row, 1);
- XX waddstr (helpwin, helptxt[i]);
- XX }
- XX if (i+1 <= nmsg && helptxt[i+1])
- XX {
- XX wmove (helpwin, row, 41);
- XX waddstr (helpwin, helptxt[i+1]);
- XX }
- XX row++;
- XX }
-
- XX wmove (helpwin, 23, 0);
- XX wstandout (helpwin);
- XX waddstr (helpwin, " <Press any key> ");
- XX wstandend (helpwin);
- XX wclrtoeol (helpwin);
- XX wrefresh (helpwin);
- XX wgetch (helpwin);
- XX werase (helpwin);
- XX wrefresh (helpwin);
- XX delwin (helpwin);
-
- XX return;
- XX}
- XX/*S reset - reset terminal to original state */
- XX/*H reset */
- XX/*E*/
- XXreset (sig)
- XXint sig;
- XX{
- XX move (23, 0);
- XX refresh ();
- XX endwin ();
- XX if (sig) fprintf (stderr, "killed with signal %d\n", sig);
- XX exit (sig);
- XX}
- XX/*S arrow - determine if current character is a cursor control key */
- XX/*H arrow */
- XX/*E*/
- XXarrow (k, r, c, type)
- XXregister int k;
- XXregister int *r;
- XXregister int *c;
- XXregister int type;
- XX{
- XX register ret = 1;
-
- XX if (k == KEY_UP)
- XX {
- XX if (*r == 0) beep ();
- XX else (*r)--;
- XX }
- XX else if (k == KEY_DOWN || k == '\n')
- XX {
- XX if (*r == 15) beep ();
- XX else (*r)++;
- XX }
- XX else if (k == KEY_LEFT || k == '\b' )
- XX {
- XX if (*c == 0)
- XX {
- XX if (*r == 0) beep ();
- XX else
- XX {
- XX *c = 15;
- XX (*r)--;
- XX }
- XX }
- XX else (*c)--;
- XX }
- XX else if (k == KEY_RIGHT)
- XX {
- XX if (*c == 15)
- XX {
- XX if (*r == 15) beep ();
- XX else
- XX {
- XX *c = 0;
- XX (*r)++;
- XX }
- XX }
- XX else (*c)++;
- XX }
- XX else if (k == KEY_HOME)
- XX {
- XX *r = *c = 0;
- XX }
- XX else
- XX {
- XX ret = 0;
- XX }
-
- XX return ret;
- XX}
- XX/*S dbg_msg - print a debug message */
- XX/*H dbg_msg */
- XX/*E*/
- XXdbg_msg (msg)
- XXregister char *msg;
- XX{
- XX if (debug && !dump)
- XX {
- XX errmsg (msg);
- XX }
-
- XX return;
- XX}
- XX/*S instr - get a character string from the terminal */
- XX/*H instr */
- XX/*E*/
- XXchar *
- XXinstr ()
- XX{
- XX static char buf[512];
-
- XX register int c;
- XX register char *p = buf;
- XX register int col = 0;
-
- XX move (22, 0);
- XX clrtoeol ();
- XX refresh ();
-
- XX while ((c = getch ()) != '\r')
- XX {
- XX if (isascii (c) && isprint (c))
- XX {
- XX move (22, col);
- XX addch (c);
- XX *p++ = c;
- XX col++;
- XX }
- XX else if (c == '\b')
- XX {
- XX p--;
- XX col--;
- XX move (22, col);
- XX addch (' ');
- XX move (22, col);
- XX }
- XX refresh ();
- XX }
-
- XX refresh ();
-
- XX *p = '\0';
-
- XX return buf;
- XX}
- XX/*S getnum - retrieve a number from the terminal */
- XX/*H getnum */
- XX/*E*/
- XXlong
- XXgetnum (frst_char, hex)
- XXregister int frst_char;
- XXregister int hex;
- XX{
- XX static char buf[64];
-
- XX register int c;
- XX register char *p = buf;
- XX register int col = 0;
-
- XX register long retval = 0;
-
- XX move (22, 0);
- XX clrtoeol ();
- XX if (frst_char)
- XX {
- XX addch (frst_char);
- XX *p++ = frst_char;
- XX col++;
- XX refresh ();
- XX }
-
- XX while ((c = getch()) != '\r')
- XX {
- XX if (isascii (c))
- XX {
- XX if ((hex && isxdigit (c)) || isdigit (c))
- XX {
- XX move (22, col);
- XX addch (c);
- XX *p++ = c;
- XX col++;
- XX }
- XX else if (c == '\b')
- XX {
- XX p--;
- XX col--;
- XX move (22, col);
- XX addch (' ');
- XX move (22, col);
- XX }
- XX else
- XX {
- XX break; /* some character typing the value */
- XX }
- XX refresh ();
- XX }
- XX }
-
- XX *p = '\0';
-
- XX retval = atol (buf);
-
- XX mvprintw (22, 0, "%ld", retval);
- XX switch (c)
- XX {
- XX case 'b': /* block - 512 bytes */
- XX retval *= 512;
- XX break;
- XX case 'k': /* 1024 bytes */
- XX retval *= 1024;
- XX break;
- XX case 'l': /* long word - 4 bytes */
- XX retval *= 4;
- XX break;
- XX case 'p': /* page - 256 bytes */
- XX retval *= 256;
- XX break;
- XX case 'w': /* word - 2 bytes */
- XX retval *= 2;
- XX break;
- XX case '\r': /* just clear it for display */
- XX c = '\0';
- XX break;
- XX }
-
- XX printw ("%c -> %ld byte offset", c, retval);
- XX clrtoeol ();
-
- XX refresh ();
-
- XX return retval;
- XX}
- XX/*S search - look for an ascii string in the file */
- XX/*H search */
- XX/*E*/
- XXsearch (fid)
- XXregister int fid;
- XX{
- XX long curpos = position;
- XX long currec = recno;
-
- XX char lrecord[sizeof record + 1];
-
- XX register int i;
- XX register int matched = 0;
- XX register int srch_len;
-
- XX register char *cp = instr ();
- XX register char *rp;
-
- XX int row, col;
-
- XX srch_len = strlen (cp);
- XX copyrec (record, lrecord, sizeof record);
- XX lrecord[256] = '\0';
-
- XX pbrk = 0;
-
- XX wmove (errwin, 0, 0);
- XX wstandout (errwin);
- XX wmove (errwin, 0, 40);
- XX wstandend (errwin);
- XX wmove (errwin, 0, 1);
- XX waddstr (errwin, "..searching record ");
- XX getyx (errwin, row, col);
-
- XX do
- XX {
- XX mvwprintw (errwin, row, col, "%ld", currec);
- XX wrefresh (errwin);
-
- XX for (i = 0, rp = lrecord, matched = 0;
- XX !matched && i < 256;
- XX rp++, i++)
- XX {
- XX if (*cp == *rp && !strncmp (cp, rp, srch_len))
- XX {
- XX matched = 1;
- XX break;
- XX }
- XX }
-
- XX if (!matched)
- XX {
- XX bytes = bread (fid, lrecord, 256, block);
- XX currec++;
- XX lrecord[256] = '\0';
- XX }
- XX } while (!pbrk && bytes && !matched);
-
- XX if (matched)
- XX {
- XX recno = currec;
- XX stay = 0;
- XX copyrec (record, unch_rec, sizeof record);
- XX werase (errwin);
- XX wrefresh (errwin);
- XX }
- XX else
- XX {
- XX errmsg ("String %s not found", cp);
- XX stay = 1;
- XX }
-
- XX return;
- XX}
- XXerrmsg (fmt, arg1, arg2, arg3, arg4)
- XXregister char *fmt;
- XXregister char *arg1;
- XXregister char *arg2;
- XXregister char *arg3;
- XXregister char *arg4;
- XX{
- XX int y, x;
-
- XX if (!dump)
- XX {
- XX getyx (stdscr, y, x);
- XX wmove (errwin, 0, 0);
- XX wstandout (errwin);
- XX wprintw (errwin, fmt, arg1, arg2, arg3, arg4);
- XX wstandend (errwin);
- XX wclrtoeol (errwin);
- XX wrefresh (errwin);
- XX move (y, x);
- XX }
- XX else
- XX {
- XX fprintf (stderr, fmt, arg1, arg2, arg3, arg4);
- XX }
- XX return;
- XX}
- XXoutstr (fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
- XXregister char *fmt;
- XXregister char *arg1;
- XXregister char *arg2;
- XXregister char *arg3;
- XXregister char *arg4;
- XXregister char *arg5;
- XXregister char *arg6;
- XXregister char *arg7;
- XX{
- XX if (dump) printf (fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
- XX else printw (fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
-
- XX return;
- XX}
- XXoutch (ch)
- XXregister char ch;
- XX{
- XX if (dump) putchar (ch);
- XX else addch (ch);
-
- XX return;
- XX}
- @//E*O*F bpatch.c//
- chmod u=rw,g=rw,o=rw $OUT
-
- echo Inspecting for damage in transit...
- temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
- trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
- cat > $temp <<\!!!
- 28 259 1521 README
- 20 83 485 Makefile
- 138 990 5412 bpatch.1
- 1749 5447 35893 bpatch.c
- 1935 6779 43311 total
- !!!
- wc README Makefile bpatch.1 bpatch.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
- if test -s $dtemp ; then
- echo "Ouch [diff of wc output]:"
- cat $dtemp
- STATUS=1
- elif test $STATUS = 0 ; then
- echo "No problems found."
- else
- echo "WARNING -- PROBLEMS WERE FOUND..."
- fi
- exit $STATUS
-